﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Win32;

using WpfElevator.ElevatorPart;
using WpfElevator.GlobalConstant;
using WpfElevator.ControlPart;
using ControlLib;
using AbstractFramework.Display;
using AbstractFramework.LogicControl;
using AbstractFramework.Constant;
using WpfElevator.RequisitionPart;
using System.Threading;
using System.Windows.Media.Animation;
using System.Xml;

namespace ElevatorEmulator
{
    /// <summary>
    /// Interaction logic for Config.xaml
    /// </summary>
    public partial class Config : Window
    {
        private List<int[]> elevatorList = new List<int[]>();//电梯列表，每一个电梯用一组整数表示，整数代表禁止停靠的楼层
        private int floorNum;   //楼层数目
        private EventGenerateMode eventGenerateMode;
        private int scheduleNo; //调度策略编号
        //
        private XmlNodeList scheduleList;

        public Config()
        {
            InitializeComponent();
            txtEventMode.SelectedIndex = 0;
            txtStrategy.SelectedIndex = 0;
            scheduleList = ControllerFactory.getScheduleList();
            foreach(XmlNode s in scheduleList)
            {
                ComboBoxItem newItem = new ComboBoxItem();
                newItem.Content = s.Attributes["name"].Value;
                txtStrategy.Items.Add(newItem);
            }
        }

        //弹出添加电梯的窗口
        private void btnAddElevator_Click(object sender, RoutedEventArgs e)
        {
            AddElevator dialog = new AddElevator(this);
            dialog.Owner = this;
            dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            dialog.ShowDialog();
        }

        //打开文件
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDlg = new OpenFileDialog();
            openFileDlg.Multiselect = false;
            if (openFileDlg.ShowDialog().Value)
            {
                txtFileName.Text = openFileDlg.FileName;
            }
        }

        //选择了一个事件产生模式
        private void txtEventMode_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (txtEventMode.SelectedIndex == 1)
            {
                lblFileName.IsEnabled = true;
                txtFileName.IsEnabled = true;
                btnBrowseFile.IsEnabled = true;
            }
            else
            {
                lblFileName.IsEnabled = false;
                txtFileName.IsEnabled = false;
                btnBrowseFile.IsEnabled = false;
            }
        }

        private void btnNext1_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                this.floorNum = Int32.Parse(txtFloorsNumber.Text);
            }
            catch
            {
                MessageBox.Show("请输入一个整数！", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            goToStep(2);
        }

        private void goToStep(int stepId)
        {
            Storyboard storyBoard = new Storyboard();

            //获取当前位置
            Thickness from = Step1.Margin;
            Thickness to = new Thickness(from.Left, (-270) * (stepId - 1), from.Right, from.Bottom);//用Math.Floor()进行下取整
            //创建动画
            ThicknessAnimation thicknessAnimation = new ThicknessAnimation(from, to, new Duration(TimeSpan.FromMilliseconds(300)));
            Storyboard.SetTarget(thicknessAnimation, Step1);
            Storyboard.SetTargetProperty(thicknessAnimation, new PropertyPath(Rectangle.MarginProperty));
            storyBoard.Children.Add(thicknessAnimation);


            Thickness from1 = Step2.Margin;
            Thickness to1 = new Thickness(from1.Left, Math.Min((-270) * (stepId - 2),0), from1.Right, from1.Bottom);

            ThicknessAnimation thicknessAnimation1 = new ThicknessAnimation(from1, to1, new Duration(TimeSpan.FromMilliseconds(300)));
            Storyboard.SetTarget(thicknessAnimation1, Step2);
            Storyboard.SetTargetProperty(thicknessAnimation1, new PropertyPath(Rectangle.MarginProperty));
            storyBoard.Children.Add(thicknessAnimation1);


            Thickness from2 = Step3.Margin;
            Thickness to2 = new Thickness(from2.Left, Math.Min((-270) * (stepId - 3),0), from2.Right, from2.Bottom);

            ThicknessAnimation thicknessAnimation2 = new ThicknessAnimation(from2, to2, new Duration(TimeSpan.FromMilliseconds(300)));
            Storyboard.SetTarget(thicknessAnimation2, Step3);
            Storyboard.SetTargetProperty(thicknessAnimation2, new PropertyPath(Rectangle.MarginProperty));
            storyBoard.Children.Add(thicknessAnimation2);

            //动画播放
            storyBoard.DecelerationRatio = 1;
            storyBoard.Begin();
        }

        public void AddElevator(string forbidenFloors)
        {
            string[] strarrFbdFloors = forbidenFloors.Split(new char[] { ',' });
            int[] intarrFbdFloors;
            if (forbidenFloors == "")
            {
                intarrFbdFloors = new int[0];
            }
            else
            {
                intarrFbdFloors = new int[strarrFbdFloors.Length];
                try
                {
                    for (int i = 0; i < strarrFbdFloors.Length; i++)
                    {
                        intarrFbdFloors[i] = Int32.Parse(strarrFbdFloors[i]);
                        if (intarrFbdFloors[i] < 1 || intarrFbdFloors[i] > floorNum)
                        {
                            MessageBox.Show("没有第" + intarrFbdFloors[i] + "层楼，请重新添加", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                            return;
                        }
                    }
                }
                catch
                {
                    MessageBox.Show("请输入一个整数，或多个用逗号隔开的整数", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }
            elevatorList.Add(intarrFbdFloors);

            ListBoxItem newItems = new ListBoxItem();
            newItems.Content = "电梯" + (listBoxElevator.Items.Count + 1);
            if (forbidenFloors != "")
            {
                newItems.Content += "：禁止楼层为" + forbidenFloors;
            }
            listBoxElevator.Items.Add(newItems);
        }

        private void btnDelElevator_Click(object sender, RoutedEventArgs e)
        {
            int selectedIndex = listBoxElevator.SelectedIndex;
            if (selectedIndex == -1)
            {
                MessageBox.Show("请选择要删除的电梯", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            for (int i = selectedIndex + 1; i < listBoxElevator.Items.Count; i++)
            {
                ((ListBoxItem)listBoxElevator.Items[i]).Content = ((string)((ListBoxItem)listBoxElevator.Items[i]).Content).Replace("电梯" + (i + 1), "电梯" + i);
            }
            listBoxElevator.Items.RemoveAt(selectedIndex);
            elevatorList.RemoveAt(selectedIndex);
        }

        private void btnPre2_Click(object sender, RoutedEventArgs e)
        {
            goToStep(1);
        }



        private void btnNext2_Click(object sender, RoutedEventArgs e)
        {
            if (elevatorList.Count == 0)
            {
                MessageBox.Show("请至少添加一部电梯", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            goToStep(3);
        }

        private void btnPre3_Click(object sender, RoutedEventArgs e)
        {
            goToStep(2);
        }

        private void btnNext3_Click(object sender, RoutedEventArgs e)
        {
            if (txtEventMode.SelectedIndex == -1)
            {
                MessageBox.Show("请选择事件产生模式", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            if (txtEventMode.SelectedIndex == 1 && txtFileName.Text == "")
            {
                MessageBox.Show("请选择输入数据文件", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            eventGenerateMode = (EventGenerateMode)txtEventMode.SelectedIndex;
            goToStep(4);
        }

        private void btnPre4_Click(object sender, RoutedEventArgs e)
        {
            goToStep(3);
        }

        //完成配置，在该方法中开始初始化主窗口
        private void btnNext4_Click(object sender, RoutedEventArgs e)
        {
            int elevatorNum = listBoxElevator.Items.Count;
            scheduleNo = txtStrategy.SelectedIndex;//SelectedIndex从0开始，所以加1.
            XmlNode selectedSchdule =  scheduleList[scheduleNo];
            string strClass = selectedSchdule.Attributes["class"].Value;
            /////初始化后台功能，包括：多部电梯、一个控制器
            //IController controller = ControllerFactory.getController(scheduleNo);
            IController controller = ControllerFactory.getController1(strClass);
            IElevator[] elevator = new Elevator[elevatorNum];
            IButtonFactory buttonFactory = new ButtonFactory();
            IElevatorDisplay[] elevatorDisplays;
            IInsideIndicatorDisplay[] insideIndicatorDisplays;
            IInsideButtonPanelDisplay[] insideButtonPanelDisplays;
            IOutsideButtonPanelDisplay[] outsideButtonPanelDisplays;
            IFloorIndicatorDisplay[] upFloorIndicatorDisplays;
            IFloorIndicatorDisplay[] downFloorIndicatorDisplays;
            //初始化全局统计类，用于进行数据统计和计算
            SystemConstant.uniqueStatistic = Statistic.getStatistic(elevatorNum);
            //ITimer[] timer = new Timer[elevatorNum];//一个电梯对应一个计时器
            //long[] idleTime = new long[elevatorNum];

            for (int i = 0; i < elevatorNum; i++)
            {
                elevator[i] = new Elevator(i, elevatorList.ElementAt(i), controller);
                //timer[i] = new Timer();
                //idleTime[i] = 0;
            }
            controller._Elevator = elevator;//将多部电梯对象对应到controller对象上
            //controller._Time = timer;
            //controller._IdleTime = idleTime;
            GConstant.controller = (IController)controller;
            
            Main m1 = new Main();
            m1.initialize(floorNum, elevatorNum, elevator, buttonFactory, out elevatorDisplays, out insideIndicatorDisplays, out insideButtonPanelDisplays,
                         out outsideButtonPanelDisplays, out upFloorIndicatorDisplays, out downFloorIndicatorDisplays);
            for (int i = 0; i < elevatorNum; i++)//将每个elevator和elevatorDisplay对象一一对应
            {
                elevator[i].Elevator_Display = elevatorDisplays[i];
                elevator[i].UpFloor_Indicator = upFloorIndicatorDisplays;//将upFloorIndicator对应到每部电梯
                elevator[i].DownFloor_Indicator = downFloorIndicatorDisplays;//将downFloorIndicator对应到每部电梯
                elevator[i].OutsideButtonPanel = outsideButtonPanelDisplays;//所有电梯共享同一个外部按钮数组
                elevator[i].InsideButtonPanel = insideButtonPanelDisplays[i];
                elevator[i].Inside_Indicator = insideIndicatorDisplays[i];
                elevator[i].Inside_Indicator.showText("1");//初始位置都是1层
            }
            m1.Show();
            
            this.Close();
            //SystemConstant.globalTimer.creatTimer();//开始仿真计时
            //SystemConstant.uniqueStatistic.GlobalTimer.creatTimer();//开始仿真计时

            if (eventGenerateMode == EventGenerateMode.FileMode)//请求从文本读入
            {
                FileRequisition fileRequisition = new FileRequisition(floorNum, elevatorNum, txtFileName.Text, this.Dispatcher);
                
                Thread thread = new Thread(fileRequisition.createNewRequisition);
                thread.Start();
                //fileRequisition.createNewRequisition();
            }
            else if (eventGenerateMode == EventGenerateMode.RandomMode)//随机产生请求
            {
                RandomRequisition randomRequisition = new RandomRequisition(floorNum, elevatorNum, this.Dispatcher);
                //randomRequisition.createNewRequisition();
                Thread thread = new Thread(randomRequisition.createNewRequisition);
                thread.Start();
            }
            else
                ;
            //elevator[0].moveTo(4);
            // elevator[0].moveTo(2);
        }
       
    }
    
}